package com.link.base.base.product.service;

import com.alibaba.fastjson.JSONObject;
import com.link.base.base.common.dao.mybatis.mapper.AttachmentMapper;
import com.link.base.base.common.dao.mybatis.mapper.ImageMapper;
import com.link.base.base.common.model.Attachment;
import com.link.base.base.common.model.Image;
import com.link.base.base.common.service.AttachmentService;
import com.link.base.base.common.service.AttachmentServiceImpl;
import com.link.base.base.coupons.model.CollectRecord;
import com.link.base.base.coupons.model.Coupons;
import com.link.base.base.coupons.service.CollectRecordService;
import com.link.base.base.coupons.service.CouponsService;
import com.link.base.base.mpconfig.model.Mp;
import com.link.base.base.mpconfig.service.MpService;
import com.link.base.base.mpconfig.service.MpTokenService;
import com.link.base.base.mvg.dao.mybatis.product.mapper.ProductTagMvgMapper;
import com.link.base.base.mvg.model.Mvg;
import com.link.base.base.product.controller.ProductController;
import com.link.base.base.product.dao.mybatis.mapper.ProductMapper;
import com.link.base.base.product.model.*;
import com.link.base.basic.model.ListOfValue;
import com.link.base.core.basic.util.YmlConstants;
import com.link.base.user.model.CoreUser;
import com.link.core.basic.dao.KeyGenerateDao;
import com.link.core.basic.dao.mapper.BasicMapper;
import com.link.core.basic.model.UploadImgInfo;
import com.link.core.basic.service.BasicServiceException;
import com.link.core.basic.service.BasicServiceImpl;
import com.link.core.basic.service.ServiceException;
import com.link.core.cllog.LCLogger;
import com.link.core.util.*;
import com.link.core.util.redisclient.LinkRedisClient;
import org.apache.commons.io.FileUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Encoder;

import javax.annotation.Resource;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * @author unknown
 * @date unknown
 * @comments 产品操作服务
 */
@Service
public class ProductServiceImpl extends BasicServiceImpl<Product> implements ProductService {

    private static final Logger logger = LogManager.getLogger(ProductController.class);

    protected static final Map<String, String> CURRENTOPMAP = new ConcurrentHashMap<>();

    @Resource
    private ImageMapper service;
    @Resource
    private ProductMapper productMapper;
    @Resource
    private KeyGenerateDao keyGenerateDao;
    @Resource
    private PriceListService priceListService;
    @Resource
    private AttachmentService attachmentService;
    @Resource
    private ProductTagMvgMapper productTagMvgMapper;

    @Resource
    private AttachmentMapper attachmentMapper;

    @Resource
    private ProdAttrService prodAttrService;

    @Resource
    private ProdPackageService prodPackageService;

    @Resource
    private CouponsService couponsService;

    @Resource
    private CollectRecordService collectRecordService;

    @Resource
    private MpService mpService;
    @Resource
    private ProdPriceHistoryService prodPriceHistoryService;
    @Resource
    private ProdTagService prodTagService;

    @Resource
    private MpTokenService mpTokenService;

    /**
     * 模拟登陆用户名 redis key
     */
    private static final String MOCK_USERNAME_KEY = "mock_unlogin_user";

    @Override
    public BasicMapper<Product> getBasicMapper() {
        return productMapper;
    }

    @Override
    public List<Product> queryUnSelectedInOptyPage(Product record) throws Exception {
        return productMapper.queryUnSelectedInOptyPage(record);
    }

    /**
     * HuangLJ 通过产品的价格表id查询产品记录
     *
     * @param priceListItem 产品记录
     * @return 产品List
     * @throws Exception 报错
     */
    @Override
    public List<Product> queryProductByPriceHeadId(PriceListItem priceListItem) throws Exception {
        return productMapper.queryProductByPriceHeadIdPage(priceListItem);
    }

    @Override
    public List<Image> imgUpload(List<MultipartFile> myfiles) throws ServiceException {
        List<Image> list = new ArrayList<Image>();
        CoreUser user = UserUtil.getUser();
        Random random = new Random();
        String realativPath = "/web/product/" + user.getId() + "/" + DateUtil.dateToStr(new Date(), "yyyyMMddHHmmss");
        String realPath = YmlConstants.getPortalShareFileDir() + realativPath;
        try {
            for (MultipartFile myfile : myfiles) {
                String originalName = myfile.getOriginalFilename();
                //文件类型(后缀)
                String fileType = "";
                try {
                    fileType = originalName.substring(originalName.lastIndexOf('.') + 1).toLowerCase();
                } catch (Exception e) {
                    LCLogger.withException(e);
                    fileType = "";
                }
                String newfileName = user.getId() + DateUtil.dateToStr(new Date(), "yyyyMMddHHmmss") + random.nextInt(100)
                        + originalName.substring(originalName.lastIndexOf('.'));
                try {
                    FileUtils.copyInputStreamToFile(myfile.getInputStream(), new File(realPath, newfileName));
                } catch (IOException e) {
                    LCLogger.withException(e);
                    throw new ServiceException("PRODUCT-017");
                }
                Image img = new Image();
                img.setId(keyGenerateDao.keyGenerate());
                String strImg = realPath + "/" + newfileName;
                strImg = strImg.substring(strImg.lastIndexOf(",") + 1);
                String binaryImg = AttachmentServiceImpl.getImageBinary(strImg, fileType);
                UploadImgInfo ui = ImageUtil.saveImageAndLessImage(binaryImg, "product", String.valueOf(img.getId()));
                img.setUrl(realativPath + "/" + newfileName);
                img.setSmallurl(ui.getFileLessHtppPath());
                img.setBigurl(ui.getBigfileHtppPath());
                img.setAttachmentSize(String.valueOf(myfile.getSize()));
                img.setAttachmentName(newfileName);
                img.setImgdesc("web端上传");
                img.setAttachmentOriginal(originalName);
                img.setAttachmentType(myfile.getContentType());
                service.imageInsert(img);
                list.add(img);
            }
            return list;
        } catch (Exception e) {
            LCLogger.withException(e);
            throw new ServiceException("PRODUCT-018");
        }
    }

    @Override
    @Transactional(rollbackFor = ServiceException.class)
    public void productImageUpate(Product record, List<Image> list) throws ServiceException {
        try {
            for (Image img : list) {

                record.setProdImgId(img.getId());
                productMapper.productImageUpdate(record);
            }
        } catch (Exception e) {
            LCLogger.withException(e);
            throw new ServiceException("PRODUCT-019");
        }
    }

    @Override
    public void prodDetailsUpdate(Product record) throws Exception {
        if (record.getId() == null) {
            throw new ServiceException("PUBLIC-007");
        }
        productMapper.prodDetailsUpdate(record);
    }


    @Override
    public void prodModelUpdate(Product record) throws ServiceException {
        try {
            productMapper.prodModelUpdate(record);
        } catch (Exception e) {
            LCLogger.withException(e);
            throw new ServiceException("PRODUCT-020");
        }
    }

    @Override
    public List<Product> queryProdOrderlistPage(Product entity) throws Exception {
        return productMapper.queryProdOrderlistPage(entity);
    }

    @Override
    public List<Product> queryProdWithAcctPricePage(Product entity) {
        return productMapper.queryProdWithAcctPricePage(entity);
    }

    @Override
    public Product queryProdWithAcctPriceById(Product entity) throws Exception {
        if (entity.getId() == null) {
            throw new Exception("ID不能为空。");
        }
        return productMapper.queryProdWithAcctPriceById(entity);
    }

    @Override
    public List<Product> queryProdWithAcctPriceByPcyId(Product entity) throws Exception {
        if (StringUtils.isBlank(entity.getAttr1())) {
            throw new Exception("政策ID不能为空。");
        }
        if (entity.getAcctId() == null) {
            throw new Exception("AcctId不能为空。");
        }
        return productMapper.queryProdWithAcctPriceByPcyId(entity);
    }

    @Override
    public List<Product> queryProdWithAcctPriceByPcyResultId(Product record) throws Exception {
        if (StringUtils.isBlank(record.getAttr1())) {
            throw new Exception("政策ID不能为空。");
        }
        if (record.getAcctId() == null) {
            throw new Exception("AcctId不能为空。");
        }
        return productMapper.queryProdWithAcctPriceByPcyResultIdPage(record);
    }


    /**
     * 根据价格头查询未选择的产品
     *
     * @param priceListItem 价格头
     * @return 产品列表
     * @throws Exception
     */
    @Override
    public List<Product> queryUnSelectedInPriceListDetailPage(PriceListItem priceListItem) throws Exception {
        return productMapper.queryUnSelectedInPriceListDetailPage(priceListItem);
    }

    @Override
    public List<Product> queryPromoPriceByProduct(Product record) throws Exception {
        List<Product> list = productMapper.queryPromoPriceByProduct(record);
        return list;
    }

    @Override
    public List<Product> queryUnSelectedInDealerPriceListPage(Product record) throws Exception {
        Long acctId = record.getAcctId();
        if (acctId == null) {
            throw new ServiceException("PRODUCT-009");
        }
        PriceList priceList = priceListService.queryDealerSalePriceHead(acctId);
        if (priceList == null) {
            throw new ServiceException("PRODUCT-021");
        }
        Long priceId = priceList.getId();
        if (priceId == null) {
            throw new ServiceException("PRODUCT-022");
        }
        record.setPriceId(priceId);
        List<Product> list = productMapper.queryUnSelectedInDealerPriceListPage(record);
        return list;
    }


    @Override
    public List<Product> queryUnSelectedInPurchasePlanListPage(Product record) throws Exception {
        Long acctId = record.getAcctId();
        if (acctId == null) {
            throw new ServiceException("PRODUCT-009");
        }
        PriceList priceList = priceListService.queryDealerSalePriceHead(acctId);
        if (priceList == null) {
            throw new ServiceException("PRODUCT-021");
        }
        Long priceId = priceList.getId();
        if (priceId == null) {
            throw new ServiceException("PRODUCT-022");
        }
        record.setPriceId(priceId);
        List<Product> list = productMapper.queryUnSelectedInPurchasePlanListPage(record);
        return list;
    }


    /**
     * HuangLJ
     *
     * @param product 产品
     * @return 附件列表
     * @throws Exception 报错
     */
    @Override
    public List<Attachment> queryProductPicByProdId(Product product) throws Exception {
        Product productRet = productMapper.queryById(product);
        Attachment attachmentQuery = new Attachment();
        attachmentQuery.setTotalFlag(true);
        attachmentQuery.setPageFlag(false);
        attachmentQuery.setModuleType("noType");
        attachmentQuery.setHeadId(product.getId());
        List<Attachment> attachmentList = attachmentService.queryByExamplePage(attachmentQuery);

        Long prodImgId = productRet.getProdImgId();
        if (prodImgId != null) {
            for (Attachment attachment : attachmentList) {
                if (attachment.getId().equals(prodImgId)) {
                    //如果是主要图片Id，则设置主要图片标识
                    attachment.setIsDefault("Y");
                } else {
                    attachment.setIsDefault("N");
                }
            }
        }
        return attachmentList;
    }

    @Override
    public List<Product> queryProductWithAcctPricePage(Product t) throws Exception {
        return productMapper.queryProductWithAcctPricePage(t);
    }

    @Override
    public Product queryProdById(Product t) throws Exception {
        Product p = this.queryById(t);
        //如果不为空，那么就查询标签
        if (!Objects.isNull(p)) {
            Mvg mvg = new Mvg();
            mvg.setPageFlag(false);
            //当前用户的账套
            mvg.setCorpid(t.getCorpid());
            //当前产品id
            mvg.setMvgParentId(p.getId());
            List<Tag> tags = productTagMvgMapper.queryTagAndProdPage(mvg);
            p.setTags(tags);
        }
        return p;
    }

    @Override
    @Transactional(rollbackFor = ServiceException.class)
    public void update(Product product) throws Exception {
        if (StringUtils.equals(product.getActionType(),"1") || StringUtils.equals(product.getActionType(),"2")) {
            checkProd(product);
        }
        String code = product.getProdCode();
        Long corpId = product.getCorpid();
        String intergraionId = product.getIntegrationId();
        String compStr = code + corpId;
        if (!StringUtils.isNull(intergraionId)) {
            compStr = compStr + intergraionId;
        }
        try {
            if (checkExists(product, false)) {
                throw new ServiceException("PRODUCT-023");
            }
            super.update(product);
        } finally {
            CURRENTOPMAP.remove(compStr);
        }
    }

    /**
     * 商品上下架校验
     * @author 路江
     * @param product
     * @throws Exception
     */
    private void checkProd(Product product) throws Exception {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        String date = format.format(new Date());
        // 小程序商品上架
        Boolean mpVisibleY = StringUtils.equals(product.getMpVisible(),"Y") && StringUtils.equals(product.getActionType(),"1");
        // 小程序商品下架
        Boolean mpVisibleN = StringUtils.equals(product.getMpVisible(),"N") && StringUtils.equals(product.getActionType(),"1");
        //  积分商城上架
        Boolean integralMallVisibleY = StringUtils.equals(product.getIntegralMallVisible(),"Y") && StringUtils.equals(product.getActionType(),"2");
        //  积分商城下架
        Boolean integralMallVisibleN = StringUtils.equals(product.getIntegralMallVisible(),"N") && StringUtils.equals(product.getActionType(),"2");

        // 小程序商品上架，积分商品上架
        if (mpVisibleY || integralMallVisibleY) {
            Boolean success = false;
            if (StringUtils.equals(product.getProdGoodType(),"Good") || StringUtils.equals(product.getProdGoodType(),"Pack")) {
                // 如果类型为Good/Pack，则正常更改上架状态，记录上架时间
                success = true;
            } else if (StringUtils.equals(product.getProdGoodType(),"Prod")
                    && product.getParentProdId() != null) {
                Product parentProd = new Product();
                parentProd.setId(product.getParentProdId());
                parentProd = this.queryById(parentProd);
                // 校验其父产品是否是上架状态 Y：上架
                if (StringUtils.equals(parentProd.getMpVisible(),"Y")) {
                    success = true;
                } else {
                    throw new Exception("所属商品未上架，该产品无法上架");
                }
            }
            // 记录上架时间 1：小程序商品上架， 2：积分商城上架
            if (success && mpVisibleY) {
                product.setMpVisibleDate(date);
            } else if (success && integralMallVisibleY) {
                product.setIntegralMallVisibleDate(date);
            }
        } else if (mpVisibleN || integralMallVisibleN ) {
            Boolean success = false;
        // 小程序商品下架，积分商品下架
            if (StringUtils.equals(product.getProdGoodType(),"Pack")) {
                // 如果类型为Pack,则正常下架，并记录下架时间
                success = true;
            } else if (StringUtils.equals(product.getProdGoodType(),"Prod")) {
                if (product.getParentProdId() == null) {
                    // 判断其是否有父产品，如果没有，正常下架，记录时间
                    success = true;
                } else {
                    Product sunProd = new Product();
                    sunProd.setParentProdId(product.getParentProdId());
                    sunProd.setMpVisible("Y");
                    List<Product> sunList = this.queryByExamplePage(sunProd);
//                    如果有父产品，则判断该产品是否是父产品下最后一个未下架的产品，
                    if (sunList.size() == 1) {
                        throw new Exception("请先下架所属商品");
                    } else {
                        // 如果不是，则正常下架，并记录下架时间
                        success = true;
                    }
                }
            } else if (StringUtils.equals(product.getProdGoodType(),"Good")) {
                // 下架所有子产品
                Product sunProd = new Product();
                sunProd.setParentProdId(product.getId());
                sunProd.setMpVisible("Y");
                List<Product> sunList = this.queryByExamplePage(sunProd);
                for (int i = 0 ; i < sunList.size() ; i++) {
                    sunList.get(i).setMpVisible("N");
                    productMapper.update(sunList.get(i));
                }
                success = true;
            }
            // 记录下架时间
            if (success && mpVisibleN) {
                product.setDownTime(date);
            } else if (success && integralMallVisibleN) {
                product.setIntegralMallInvisibleDate(date);
            }

        }
    }

    @Override
    @Transactional(rollbackFor = ServiceException.class)
    public void insert(Product product) throws Exception {
        String code = product.getProdCode();
        Long corpId = product.getCorpid();
        String intergraionId = product.getIntegrationId();
        String compStr = code + corpId;
        if (!StringUtils.isNull(intergraionId)) {
            compStr = compStr + intergraionId;
        }
        try {
            if (checkExists(product, true)) {
                throw new ServiceException("PRODUCT-023");
            }
            super.insert(product);
        } finally {
            CURRENTOPMAP.remove(compStr);
        }
    }

    /**
     * Hlj 2018年06月21日
     *
     * @param product 产品对象
     * @return 是否存在
     * @throws Exception 报错
     */
    private Boolean checkExists(Product product, Boolean insertFlag) throws Exception {
        Boolean flag = false;
        String code = product.getProdCode();
        Long corpId = product.getCorpid();
        String intergraionId = product.getIntegrationId();
        String compStr = code + corpId;
        if (!StringUtils.isNull(intergraionId)) {
            compStr = compStr + intergraionId;
        }
        if (CURRENTOPMAP.containsKey(compStr)) {
            return true;
        }
        CURRENTOPMAP.put(compStr, "");
        Product productQuery = new Product();
        productQuery.setIntegrationId(intergraionId);
        productQuery.setProdCode(code);
        productQuery.setPageFlag(false);
        List<Product> productList = productMapper.queryByExamplePage(productQuery);
        if (productList != null && productList.size() > 0 && insertFlag) {
            return true;
        }
        if (productList != null && productList.size() == 1) {
            if (!productList.get(0).getId().equals(product.getId())) {
                flag = true;
            }
        } else if (productList != null && productList.size() > 1) {
            flag = true;
        }
        return flag;
    }

    /**
     * 重定义upsert方法
     *
     * @throws Exception
     */
    @Override
    @Transactional(rollbackFor = ServiceException.class)
    public void prodUpsert(Product entity) throws Exception {
        Product prod = entity;
        if (isInsertFlag(prod)) {
            insert(prod);
            List<Tag> tags = prod.getTags();
            if (!Objects.isNull(tags) && !tags.isEmpty()) {
                tags.stream().forEach(tag -> {
                    Mvg mvg = new Mvg();
                    Long id = keyGenerateDao.keyGenerate();
                    mvg.setId(id);
                    mvg.setCorpid(prod.getCorpid());
                    //产品id
                    mvg.setMvgParentId(prod.getId());
                    //标签id
                    mvg.setMvgSubsetId(tag.getId());
                    try {
                        productTagMvgMapper.insert(mvg);
                    } catch (Exception e) {
                        LCLogger.withException(e);
                        throw new ServiceException("PRODUCT-024");
                    }
                });
            }
        } else {
            update(prod);
            Mvg mvg = new Mvg();
            mvg.setPageFlag(false);
            mvg.setCorpid(prod.getCorpid());
            mvg.setMvgParentId(prod.getId());
            //查询该产品的下所标签
            //如果前端传入标签，那么就对比删除插入
            //如果没有传入，那么就删除所有
            List<Tag> fTags = prod.getTags();
            if (Objects.isNull(fTags) || fTags.isEmpty()) {
                productTagMvgMapper.deleteInterByTagOrProdId(mvg);
            } else {
                List<Tag> bTags = productTagMvgMapper.queryTagAndProdPage(mvg);
                //前端标签id
                List<Long> fTagIds = fTags.stream().collect(() -> new ArrayList<Long>(), (l, d) -> l.add(d.getId()), (ll, l2) -> ll.addAll(l2));
                //后端标签id  从集合对象中获取到某一个属性组合的集合
                List<Long> bTagIds = bTags.stream().collect(() -> new ArrayList<Long>(), (l, d) -> l.add(d.getId()), (ll, l2) -> ll.addAll(l2));
                //筛选前端新增加的，即前端不在后台中的
                List<Long> newTags = fTagIds.stream().filter(d -> {
                    return !bTagIds.contains(d);
                }).collect(Collectors.toList());

                //筛选后台需要删除的，即后台不在前端中的
                List<Long> delTags = bTagIds.stream().filter(d -> {
                    return !fTagIds.contains(d);
                }).collect(Collectors.toList());
                //新增不为空
                if (!Objects.isNull(newTags) && !newTags.isEmpty()) {
                    newTags.stream().forEach(t -> {
                        Mvg m = new Mvg();
                        Long id = keyGenerateDao.keyGenerate();
                        m.setId(id);
                        m.setCorpid(prod.getCorpid());
                        //产品id
                        m.setMvgParentId(prod.getId());
                        //标签id
                        m.setMvgSubsetId(t);
                        try {
                            productTagMvgMapper.insert(m);
                        } catch (Exception e) {
                            LCLogger.withException(e);
                            throw new ServiceException("PRODUCT-024");
                        }
                    });
                }
                //删除不为空
                if (!Objects.isNull(delTags) && !delTags.isEmpty()) {
                    delTags.stream().forEach(t -> {
                        Mvg m = new Mvg();
                        m.setCorpid(prod.getCorpid());
                        //产品id
                        m.setMvgParentId(prod.getId());
                        //标签id
                        m.setMvgSubsetId(t);
                        try {
                            productTagMvgMapper.deleteInterByTagOrProdId(m);
                        } catch (Exception e) {
                            LCLogger.withException(e);
                            throw new ServiceException("PRODUCT-025");
                        }
                    });
                }
            }
        }
    }

    @Override
    @Transactional(rollbackFor = ServiceException.class)
    public void deleteProdAndTagById(Product t) throws Exception {
        LCLogger.info().withMessageKey("deleteProdAndTagById")
                .withMessage("操作账套:[" + t.getLoginCorpId() + "],删除产品id：[" + t.getId() + "]").flush();
        this.deleteById(t);
        Mvg mvg = new Mvg();
        mvg.setCorpid(t.getLoginCorpId());
        mvg.setMvgParentId(t.getId());
        productTagMvgMapper.deleteInterByTagOrProdId(mvg);
    }

    /**
     * 根据查询产品及指定客户查品牌
     *
     * @param record
     * @throws Exception
     */
    @Override
    public List<ListOfValue> queryBrandList(Product record) throws Exception {
        return productMapper.queryBrandList(record);
    }

    @Override
    public List<Product> queryHotProduct(Product entity) throws Exception {
        return productMapper.queryHotProduct(entity);
    }

    /**
     * 查询不同类别产品的第一条 by lizt 20170703
     */
    @Override
    public List<Product> queryProductByType(Product entity) throws Exception {
        entity.setParType("prodMatSeries");
        return productMapper.queryProductByType(entity);
    }

    /**
     * 使用于php调用的queryById方法
     */
    @Override
    public Product queryByIdForShare(Product entity) throws Exception {
        return productMapper.queryByIdForShare(entity);
    }


    @Override
    public Product queryById(Product entity) throws Exception {
        String loginType = entity.getLoginType();
        if (StringUtils.equals(loginType,GUIDE_APP) || MP.equals(loginType)) {
            // 设置价格表id为当前登录人价格表id,导购默认会带出当前门店的价格表id
            if (entity.getPriceListId() == null) {
                CoreUser user = UserUtil.getUser();
                entity.setPriceListId(user.getPriceListId());
            }
            entity = super.queryById(entity);
            //获取产品图片信息
            Attachment attachment = new Attachment();
            attachment.setHeadId(entity.getId());
            attachment.setBigurl(entity.getProdBigImagePath());
            attachment.setSmallurl(entity.getProdSmallImagePath());
            attachment.setAttachmentPath(entity.getProdImagePath());
            List<Attachment> attachmentList = new ArrayList<Attachment>();
            attachmentList.add(attachment);
            //获取附件列表
            List<Attachment> tempList = attachmentMapper.queryAttachmentByHeadId(attachment);
            if (tempList != null && tempList.size() > 0) {
                attachmentList.addAll(tempList);
            }
            entity.setAttachmentList(attachmentList);
        } else if (StringUtils.equals(loginType,MP)) {
            /**
             * 如果是小程序登陆的话，查询附件、优惠券
             */
            Long acctId = entity.getAcctId();
            if (acctId == null) {
                acctId = UserUtil.getUser().getAcctId();
            }
            //判断是否要转品牌系列单位值列表 Y/N
            String lov = entity.getAttr4();
            String y = "Y";
            entity = queryById(entity);
            //产品系列值列表转换
            if (y.equals(lov)) {
                getLovValue(entity);
            }
            //小程序登陆查询产品详情浏览记录加1
            Product prod = new Product();
            if (prod.getPriceListId() == null) {
                prod.setPriceListId(UserUtil.getUser().getPriceListId());
            }
            prod.setId(entity.getId());
            Integer viewNum;
            if (null == entity.getViewNum()) {
                viewNum = 1;
            } else {
                viewNum = entity.getViewNum() + 1;
            }
            prod.setViewNum(viewNum);
            productMapper.updateViewNum(prod);
            Attachment attachment = new Attachment();
            attachment.setHeadId(entity.getId());
            attachment.setPageFlag(false);
            //产品附件轮播图
            List<Attachment> attachmentList = attachmentService.queryByExamplePage(attachment);
            entity.setAttachmentList(attachmentList);
            //产品适用优惠券
            entity.setAcctId(acctId);
            List<Coupons> list = (List<Coupons>) couponsService.productForCard(entity).get("rows");
            entity.setCouponsList(list);
        } else {
            entity = super.queryById(entity);
        }
        return entity;
    }

    /**
     * 品牌系列单位值列表转换
     * @param entity
     * @throws Exception
     */
    private void getLovValue(Product entity) throws Exception {
        // 一级系列
        if (StringUtils.isNotBlank(entity.getProdMatSeries())) {
            entity.setProdMatSeries(getLovValue("PROD_MAT_SERIES",entity.getProdMatSeries()));
        }
        // 二级系列
        if (StringUtils.isNotBlank(entity.getProdSecSeries())) {
            entity.setProdSecSeries(getLovValue("PROD_SEC_SERIES",entity.getProdSecSeries()));
        }
        // 三级系列
        String thirdSeries = entity.getProdThirdSeries();
        if (StringUtils.isNotBlank(thirdSeries)) {
            entity.setProdThirdSeries(getLovValue("PROD_THD_SERIES",entity.getProdThirdSeries()));
        }
        // 一级品牌
        if (StringUtils.isNotBlank(entity.getProdBrand())) {
            entity.setProdBrand(getLovValue("PROD_BRAND",entity.getProdBrand()));
        }

        // 二级品牌
        if (StringUtils.isNotBlank(entity.getProdSecBrand())) {
            entity.setProdSecBrand(getLovValue("PROD_SEC_BRAND",entity.getProdSecBrand()));
        }
        // 三级品牌
        if (StringUtils.isNotBlank(entity.getProdThirdBrand())) {
            entity.setProdThirdBrand(getLovValue("PROD_THD_BRAND",entity.getProdThirdBrand()));
        }
        // 单位
        if (StringUtils.isNotBlank(entity.getProdUnit())) {
            entity.setProdUnit(getLovValue("PROD_UNIT",entity.getProdUnit()));
        }
    }

    /**
     * @author 路江
     * 转换失败继续往下转换，值为独立源代码
     * @param lovType
     * @param lovName
     * @return
     */
    private String getLovValue(String lovType,String lovName) {
        String lovValue = lovName;
        try {
            lovValue = LovUtil.getLovName(lovType,lovName);
        } catch (Exception e) {
            LCLogger.withException("对应的值列表未维护！");
        }
        return lovValue;
    }

    @Override
    public List<Product> queryByExamplePage(Product entity) throws Exception {
        List<Product> list = null;
        if (GUIDE_APP.equals(entity.getLoginType()) || MP.equals(entity.getLoginType())) {
            // 设置价格表id为当前登录人价格表id,导购默认会带出当前门店的价格表id
            if (entity.getPriceListId() == null) {
                CoreUser user = UserUtil.getUser();
                entity.setPriceListId(user.getPriceListId());
            }
        }
        list = productMapper.queryByExamplePage(entity);
        return list;
    }

    /**
     * 查询产品系列 且去除重复项 用于筛选
     */
    @Override
    public List<Product> queryProdMatSeries(Product record) throws Exception {
        return productMapper.queryProdMatSeries(record);
    }

    /**
     * 按照创建时间,查询维护了二级系列的产品的第一条数据
     *
     * @param record 产品
     * @return 产品列表
     * @throws Exception 异常信息
     */
    @Override
    public Map<String, List<Product>> queryProdSecSeries(Product record) throws Exception {
        Map<String, List<Product>> result = new LinkedHashMap<>();

        List<Product> productList = productMapper.queryProdSecSeries(record);
        List<Product> prodThirdSeries = null;
        if (productList != null && productList.size() > 0) {
            for (Product product : productList) {
                if (result.containsKey(product.getProdSecSeries())) {
                    prodThirdSeries = result.get(product.getProdSecSeries());
                } else {
                    prodThirdSeries = new ArrayList<>();
                }
                prodThirdSeries.add(product);
                result.put(product.getProdSecSeries(), prodThirdSeries);
            }
        }
        return result;
    }

    /**
     * 根据订单行上的产品,获取销售数量最高的5个产品
     *
     * @param record 产品信息
     * @return 产品列表
     * @throws Exception 异常信息
     */
    @Override
    public List<Product> queryHotProductByOrder(Product record) throws Exception {
        return productMapper.queryHotProductByOrder(record);
    }

    @Override
    public Map<String, Object> queryByGoodProdId(Product product) throws Exception {
        Product goodProduct = new Product();
        String good = "Good";
        String pack = "Pack";
        if (good.equals(product.getProdGoodType())) {
            //商品
            goodProduct.setParentProdId(product.getId());
            goodProduct.setPageFlag(false);
            List<Product> productList = this.queryByExamplePage(goodProduct);
            for (int i = 0; i < productList.size(); i++) {
                Product prod = productList.get(i);
                ProdAttr prodAttr = new ProdAttr();
                prodAttr.setProdId(prod.getId());
                prodAttr.setPageFlag(false);
                List<ProdAttr> prodAttrList = prodAttrService.queryByExamplePage(prodAttr);
                prod.setProdAttrList(prodAttrList);
            }
            goodProduct.setProductList(productList);
        } else if ((pack).equals(product.getProdGoodType())) {
            //组合产品
            ProdPackage prodPackage = new ProdPackage();
            prodPackage.setProductId(product.getId());
            prodPackage.setPageFlag(false);
            List<ProdPackage> prodPackageList = prodPackageService.queryByExamplePage(prodPackage);
            List<Product> packProduct = new ArrayList<>();
            for (int i = 0; i < prodPackageList.size(); i++) {
                Product prod = new Product();
                prod.setId(prodPackageList.get(i).getPackageId());
                prod = this.queryById(prod);
                ProdAttr prodAttr = new ProdAttr();
                prodAttr.setProdId(prod.getId());
                prodAttr.setPageFlag(false);
                List<ProdAttr> prodAttrList = prodAttrService.queryByExamplePage(prodAttr);
                prod.setProdAttrList(prodAttrList);
                packProduct.add(prod);
            }
            goodProduct.setProductList(packProduct);
        } else {
            goodProduct = this.queryById(product);
            ProdAttr prodAttr = new ProdAttr();
            prodAttr.setProdId(goodProduct.getId());
            prodAttr.setPageFlag(false);
            List<ProdAttr> prodAttrList = prodAttrService.queryByExamplePage(prodAttr);
            goodProduct.setProdAttrList(prodAttrList);
        }
        Map<String, Object> map = new HashMap<>(8);
        map.put("rows", goodProduct);
        return map;
    }

    /**
     * 小程序主路径
     */
    private static final String MP_MAIN_PATH = "pages/tabs/tabs";

    /**
     * 小程序扫描二维码登路径
     */
    private static final String MP_QR_CODE_LOGIN_PATH = "pages/qrcode-login/qrcode-login";

    /**
     * 小程序商品详情路径
     */
    private static final String PRODUCT_ITEM_PATH = "pages/goods/goods-detail";

    /**
     * 小程序普通领券活动
     */
    private static final String COUPON_CAMP_PATH = "pages/active/active-detail";

    /**
     * 小程序分享领券
     */
    private static final String SHARE_COUP_CAMP_PATH = "pages/share/share";

    /**
     * 小程序邀请有礼
     */
    private static final String INVITATION_CAMP_PATH = "pages/invite/inviter-register";

    /**
     * 小程序红包
     */
    private static final String RED_PACKET_PATH = "pages/active/red-packet";

    /**
     * 问卷调查详情
     */
    private static final String QUESTION_DETAIL_PATH = "pages/questionnaire/question-detail";

    /**
     * 我的订单页面
     */
    private static final String ORDER_LIST_PAGE = "pages/order/order";

    /**
     * 会员卡领取页面
     */
    private static final String MEMBER_GETCARD_PAGE = "pages/member-card/member-card";

    @Override
    public Map<String, Object> createMiniprogramCode(Product product) throws Exception {
        LinkRedisClient j = null;
        Map<String, Object> map = new HashMap<>(8);
        //获取响应
        BufferedReader reader = null;
        HttpURLConnection httpURLConnection = null;
        try {
            CoreUser user = UserUtil.getUser();
            // 导购id
            Long guideId = null;
            // 来源字段,表明创建二维码的来源字段
            String source = product.getSource();
            // 小程序路径
            String page = null;
            // corpId
            Long corpId = product.getLoginCorpId();
            // 如果前端没有传来源,则用登陆状态做判断
            if (source == null) {
                // 用户为空,表明为无状态登陆,从请求中获取参数
                if (user == null) {
                    // 用于存放导购id,不再额外开新字段了
                    guideId = Long.parseLong(product.getAttr1());
                    source = H5;
                    corpId = product.getLoginCorpId();
                } else {
                    // 存在登陆状态用户,判断登陆设备
                    source = product.getLoginType();
                    // corpId
                    corpId = user.getLoginCorpId();
                    // 如果是导购助手,还需要获取下导购id
                    if (GUIDE_APP.equals(product.getLoginType())) {
                        // 导购助手,则导购id即为当前登录用户id
                        guideId = user.getId();
                    }
                }
            }

            // 查询小程序配置信息,只查询默认且有效的小程序配置信息
            Mp mp = new Mp();
            mp.setPageFlag(false);
            mp.setValidFlag("Y");
            mp.setMainFlag("Y");
            mp.setLoginCorpId(corpId);
            List<Mp> mpList = mpService.queryByExamplePage(mp);
            if (mpList != null && mpList.size() > 0) {
                mp = mpList.get(0);
            } else {
                throw new Exception("该帐套未维护小程序信息");
            }
            String accesstoken = mpTokenService.getMpAccessToken(mp);
            String requestUrl = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + accesstoken;
            // 转换成特定格式字符串
            URL url = new URL(requestUrl);
            httpURLConnection = (HttpURLConnection) url.openConnection();
            // 提交模式
            httpURLConnection.setRequestMethod("POST");
            httpURLConnection.setDoOutput(true);
            httpURLConnection.setDoInput(true);
            JSONObject paramJson = new JSONObject();

            j = RedisUtil.getJedis();
            // 将场景值作为redis的key,用于存储hset
            String scene = "MP_QRCODE:" + keyGenerateDao.keyGenerate();
            if (guideId != null) {
                // 导购id
                j.hset(scene, "userId", String.valueOf(guideId));
            }
            if (product.getItemType() != null) {
                // 类型
                j.hset(scene, "type", product.getItemType());
            }
            if (product.getId() != null) {
                // 对应的对象的id
                j.hset(scene, "id", String.valueOf(product.getId()));
            }
            if (source != null) {
                // 来源
                j.hset(scene, "source", source);
            }
            String memberCard = "memberCard";
            // 分享类型是产品
            if ("product".equals(product.getItemType())) {
                page = PRODUCT_ITEM_PATH;
            } else if ("activity".equals(product.getItemType())) {
                // 分享类型是活动
                switch (product.getParType()) {
                    case "InvitationCamp":
                        page = INVITATION_CAMP_PATH;
                        break;
                    case "ShareCoupCamp":
                        page = SHARE_COUP_CAMP_PATH;
                        break;
                    case "RedPacket":
                        page = RED_PACKET_PATH;
                        break;
                    default:
                        page = COUPON_CAMP_PATH;
                }
                if (product.getParType() != null) {
                    j.hset(scene, "activityType", product.getParType());
                }
            } else if ("loginQrCode".equals(product.getItemType())) {
                // 用户登陆验证
                // 暂时先使用首页,待发布后再做调整
                page = MP_MAIN_PATH;
            } else if ("question".equals(product.getItemType())) {
                page = QUESTION_DETAIL_PATH;
            } else if ("orderList".equals(product.getItemType())) {
                page = ORDER_LIST_PAGE;
            } else if (memberCard.equals(product.getItemType())) {
                page = MEMBER_GETCARD_PAGE;
            } else {
                throw new ServiceException("PRODUCT-026");
            }
            // 将参数写入到paramJson对象中
            paramJson.put("scene", scene);
            paramJson.put("page", page);
            paramJson.put("width", 430);
            paramJson.put("auto_color", true);
            // 创建请求流
            String data = JsonUtil.toString(paramJson);
            PrintWriter printWriter = new PrintWriter(httpURLConnection.getOutputStream());
            printWriter.write(data);
            printWriter.flush();
            // 根据响应,创建二维码附件图片
//          String realativPath = makeImage(product,httpURLConnection.getInputStream());
            String base64Code = getBase64FromInputStream(httpURLConnection.getInputStream());
            // 将url返回给前端
//          map.put("Url", YmlConstants.getPortalShareUrlDir() + realativPath);
            map.put("base64Code",base64Code);
        } catch (Exception e) {
            LCLogger.withException(e);
            throw new ServiceException(e.getMessage());
        } finally {
            // 将需要关闭的资源进行释放
            RedisUtil.returnResource(j);
            if (reader != null) {
                reader.close();
            }
            if (httpURLConnection != null) {
                httpURLConnection.disconnect();
            }
        }
        return map;
    }

    /**
     * 创建附件文件
     * @author LiQun
     * @date 2018/12/18
     * @param product id 产品id
     * @param inputStream 输入流
     * @return 附件目录
     */
    private String makeImage(Product product,InputStream inputStream) throws IOException {
        OutputStream os = null;
        BufferedInputStream bis = new BufferedInputStream(inputStream);
        String realativPath = null;
        try {
            realativPath = "/web/file/" + product.getId() + "/" + DateUtil.dateToStr(new Date(), "yyyyMMddHHmmss") + ".jpg";
            String codeUrl = YmlConstants.getPortalShareFileDir() + realativPath;
            String outUrl = YmlConstants.getPortalShareFileDir() + "/web/file/" + product.getId();
            File outDir = new File(outUrl);
            outDir.mkdirs();
            os = new FileOutputStream(codeUrl);
            int len;
            byte[] arr = new byte[1024];
            while ((len = bis.read(arr)) != -1) {
                os.write(arr, 0, len);
                os.flush();
            }
            os.close();
        } catch (FileNotFoundException e) {
            LCLogger.withException(e);
            throw new ServiceException(e.getMessage());
        } finally {
            if (null != os) {
                os.close();
            }
        }
        return realativPath;
    }

    @Transactional(rollbackFor = ServiceException.class)
    @Override
    public Map<String, Object> saveProduct(Product produc) throws Exception {
        Map<String, Object> result = new HashMap<>(8);
        //Good Prod Pack :商品；产品；组合产品
        String prod = "Prod";
        String pack = "Pack";
        String good = "Good";
        if (prod.equals(produc.getProdGoodType()) || pack.equals(produc.getProdGoodType())) {
            this.upsert(produc);
            List<ProdAttr> list = produc.getProdAttrList();
            for (int i = 0; i < list.size(); i++) {
                ProdAttr prodAttr = list.get(i);
                prodAttr.setProdId(produc.getId());
                //保存属性
                prodAttrService.insert(prodAttr);
            }
            if (pack.equals(produc.getProdGoodType())) {
                List<Product> productList = produc.getProductList();
                ProdPackage prodPackage = new ProdPackage();
                if (productList.size() > 0) {
                    //保存组合产品
                    prodPackageService.insert(prodPackage);
                    prodPackage.setProductId(produc.getId());
                    prodPackage.setPackageId(prodPackage.getId());
                    prodPackageService.update(prodPackage);
                }
                Long prodPackageId = prodPackage.getId();
                for (int i = 0; i < productList.size(); i++) {
                    ProdPackage pPackage = new ProdPackage();
                    pPackage.setProductId(productList.get(i).getId());
                    pPackage.setPackageId(prodPackageId);
                    prodPackageService.insert(pPackage);
                }
            }
        } else if (good.equals(produc.getProdGoodType())) {
            //保存商品
            this.insert(produc);
        }
        result.put("success", true);
        return result;
    }

    @Override
    public List<Product> queryHasProdMatSeries(Product produc) throws Exception {
        return productMapper.queryHasProdMatSeries(produc);
    }

    @Override
    public Map<String, Object> queryByProdId(Product product) throws Exception {
        Map<String, Object> map = new HashMap<>(8);
        //是否转换属性值列表 Y/N
        String lov = product.getAttr3();
        Product prod = new Product();
        prod.setId(product.getId());
        // 商品价目类别区分
        prod = queryById(prod);
        //Good Prod Pack :商品；产品；组合产品
        Product produc = new Product();
        String pack = "Pack";
        String good = "Good";
        String prodStr = "Prod";
        String y = "Y";
        if ((good).equals(prod.getProdGoodType())) {
            getProduct(prod,lov);
        } else if (prodStr.equals(prod.getProdGoodType())) {
            //判断产品是否有父商品
            if (null == prod.getParentProdId()) {
                ProdAttr prodAttr = new ProdAttr();
                prodAttr.setProdId(prod.getId());
                prodAttr.setPageFlag(false);
                //产品属性
                List<ProdAttr> prodAttrList = prodAttrService.queryByExamplePage(prodAttr);
                //产品属性值列表转换
                if (y.equals(lov)) {
                    for (ProdAttr pa : prodAttrList) {
                        lovProdAttr(pa);
                    }
                }

                prod.setProdAttrList(prodAttrList);
            } else {
                Product pProd = new Product();
                pProd.setId(prod.getParentProdId());
                pProd = queryById(pProd);
                pProd.setAcctId(prod.getAcctId());
                prod = getProduct(pProd,lov);
            }
        } else if (pack.equals(prod.getProdGoodType())) {
            ProdPackage prodPackage = new ProdPackage();
            prodPackage.setPackageId(prod.getId());
            prodPackage.setPageFlag(false);
            //组合产品集合
            List<ProdPackage> packageList = prodPackageService.queryByExamplePage(prodPackage);
            List<Product> productList = new ArrayList<>();
            for (int i = 0; i < packageList.size(); i++) {
                Product p = new Product();
                p.setId(packageList.get(i).getProductId());
                getProduct(prod,lov);
                p = queryById(p);
                p.setProdNum(packageList.get(i).getProdNum());
                ProdAttr prodAttr = new ProdAttr();
                prodAttr.setProdId(p.getId());
                prodAttr.setPageFlag(false);
                //组合产品属性
                List<ProdAttr> prodAttrList = prodAttrService.queryByExamplePage(prodAttr);
                //产品属性值列表转换
                if (y.equals(lov)) {
                    for (ProdAttr pa : prodAttrList) {
                        lovProdAttr(pa);
                    }
                }

                p.setProdAttrList(prodAttrList);
                productList.add(p);
            }
            prod.setProductList(productList);
        }
        map.put("row", prod);
        return map;
    }

    /**
     * 产品属性值列表转换
     * @param pa
     * @throws Exception
     */
    private void lovProdAttr(ProdAttr pa) throws Exception {
        pa.setAttrOption(getLovValue("PROD_ATTR_OPTION",pa.getAttrOption()));
        pa.setAttrValue(getLovValue("PROD_ATTR_VALUE",pa.getAttrValue()));
    }

    /**
     * 获取商品下产品，产品下属性，优惠券，以及优惠券是否已经使用过
     * @author lujiang
     * @param produc
     * @return Product
     * @throws Exception
     */
    private Product getProduct(Product produc,String lov) throws Exception {
        Product product = new Product();
        product.setParentProdId(produc.getId());
        product.setPageFlag(false);
        //商品下产品
        List<Product> productList = this.queryByExamplePage(product);
        List<Product> prodList = new ArrayList<>();
        for (int i = 0; i < productList.size(); i++) {
            Product prod = productList.get(i);
            ProdAttr prodAttr = new ProdAttr();
            prodAttr.setProdId(prod.getId());
            prodAttr.setPageFlag(false);
            //产品属性
            List<ProdAttr> prodAttrList = prodAttrService.queryByExamplePage(prodAttr);
            String y = "Y";
            if (y.equals(lov)) {
                for (ProdAttr pa : prodAttrList) {
                    lovProdAttr(pa);
                }
            }

            prod.setProdAttrList(prodAttrList);
            prodList.add(prod);
        }
        produc.setProductList(prodList);
        return produc;
    }

    /**
     * 判断是否已经领取
     *
     * @author lujiang
     * @param list   优惠券list
     * @param acctId 消费者
     * @throws Exception
     */
    private void drawDownFlag(List<Coupons> list, Long acctId) throws Exception {
        for (int i = 0; i < list.size(); i++) {
            CollectRecord collectRecord = new CollectRecord();
            collectRecord.setCouponsId(list.get(i).getId());
            collectRecord.setAccntId(acctId);
            collectRecord.setClaimStatus("Received");
            collectRecord.setPageFlag(false);
            List<CollectRecord> collectRecordList = collectRecordService.queryByExamplePage(collectRecord);
            if (collectRecordList.size() > 0) {
                list.get(i).setDrawDownFlag("true");
            }
        }
    }

    @Override
    public List<Product> getGoodSalePrice(List<Product> list) throws Exception {
        for (int i = 0; i < list.size(); i++) {
            Product product = list.get(i);
            //类型为商品
            String good = "Good";
            String prodGoodType = product.getProdGoodType();
            if (good.equals(prodGoodType)) {
                Product prod = new Product();
                prod.setParentProdId(product.getId());
                prod.setPageFlag(false);
                //查询子产品
                List<Product> productList = queryByExamplePage(prod);
                List<Double> salePricelist = new ArrayList<>();
                //得到商品下产品的最小销售价赋值到展示价中
                for (Product pro : productList) {
                    salePricelist.add(pro.getSalePrice());
                }
                if (salePricelist.size() > 0) {
                    product.setSalePrice(Collections.min(salePricelist));
                }
            }
        }
        return list;
    }

    /**
     * @param product 产品信息
     * @return 排序前9的系列
     * @throws Exception
     */
    @Override
    public List<Product> queryHotThdSeries(Product product) throws Exception {
        return productMapper.queryHotThdSeries(product);
    }

    /**
     * 更改产品销量
     *
     * @param product
     * @throws Exception
     */
    @Override
    public void updateCumulateSale(Product product) throws Exception {
        productMapper.updateCumulateSale(product);
    }


    /**
     * 新建小程序产品
     * @author  wangdawei
     * @param product
     * @return
     * @throws Exception 异常信息
     */
    @Override
    @Transactional(rollbackFor = ServiceException.class)
    public Map<String,Object> newMpProd(Product product) throws Exception {
        Map<String,Object> map = new HashMap<>(8);
        //校验是否维护小程序
        this.beforUpdate(product);
        Long prodId = product.getId();
        if (prodId == null) {
            prodId = keyGenerateService.keyGenerate();
            product.setId(prodId);
        }
        // 新建产品 - 产品图册
        List<Attachment> attachmentList = product.getAttachmentList();
        for (Attachment attachment : attachmentList) {
            if ("Y".equals(attachment.getAttr1())) {
                // 新建产品 - 设置产品主图片
                product.setProdImgId(attachment.getId());
            }
        }
        // 校验产品编码是否存在
        if (checkProdCode(product.getProdCode())) {
            throw new ServiceException("PRODUCT-023");
        }
        productMapper.insert(product);
        // 新建产品标签
        List<ProdTag>  prodTagList = product.getProdTagList();
        if (!prodTagList.isEmpty()) {
            prodTagService.batchInsert(prodTagList);
        }
        List<ProdAttr> prodAttrList = product.getProdAttrList();
        if (prodAttrList.size() != 0) {
            // 批量新建产品属性
            prodAttrService.batchInsert(prodAttrList);
        }
        // 新建产品 - 新建商品 （关联产品）
        List<Product> productList = product.getProductList();
        // 新建商品
        String good = "Good";
        // 新建产品包
        String pack = "Pack";
        if (good.equals(product.getProdGoodType())) {
            if ( productList.size() != 0 ) {
                for (Product product1 : productList) {
                    product1 = this.queryById(product1);
                    product1.setParentProdId(prodId);
                    this.update(product1);
                }
            }
        } else if (pack.equals(product.getProdGoodType())) {
            List<ProdPackage>  prodPackageList = product.getPackageList();
            if (prodPackageList.size() > 0) {
                prodPackageService.batchInsert(product.getPackageList());
            }
        }
        //历史价格表里面新增一条价格历史记录
        ProdPriceHistory prodPriceHistory = new ProdPriceHistory();
        prodPriceHistory.setHeadId(prodId);
        prodPriceHistory.setStartTime(DateUtil.dateToStr(new Date(),"yyyy-MM-dd HH:mm:ss"));
        prodPriceHistory.setPrice(product.getProdPrice());
        prodPriceHistoryService.insert(prodPriceHistory);
        map.put("newRow",product);
        return map;
    }

    /**
     * 编辑小程序产品 数据回显
     * @author  wangdawei
     * @param product
     * @return
     * @throws Exception 异常信息
     */
    @Override
    public Map<String,Object> getMpProdInfo(Product product) throws Exception {
        // 获取小程序下的
        Map<String,Object> result = new HashMap<>(8);
        if (null == product) {
            throw  new ServiceException("REPORT-007");
        }
        //查询产品信息
        product = queryById(product);
        if (product.getParentProdId() != null) {
            Product p = new Product();
            p.setId(product.getParentProdId());
            p = queryById(p);
            product.setParentProdName(p.getProdName());
        }

        //查询产品下的图片信息
        Long prodId = product.getId();
        Attachment attachment = new Attachment();
        attachment.setPageFlag(false);
        attachment.setHeadId(prodId);
        List<Attachment> attachmentList = attachmentMapper.queryByExamplePage(attachment);
        // 查询产品标签
        ProdTag prodTag = new ProdTag();
        prodTag.setProdId(prodId);
        prodTag.setPageFlag(false);
        List<ProdTag> prodTagList = prodTagService.queryByExamplePage(prodTag);
        product.setProdTagList(prodTagList);
        product.setAttachmentList(attachmentList);
        switch (product.getProdGoodType()) {
            // 产品类型为Prod时带出属性信息
            case "Prod":
                List<ProdAttr> prodAttrList = this.getProdAttrList(product);
                product.setProdAttrList(prodAttrList);
                break;
            // 产品类型为Good时带出关联产品
            case "Good":
                List<Product> productList = this.getGoodProdList(product);
                product.setProductList(productList);
                break;
            // 产品类型为Pack时带出组合产品信息
            case "Pack":
                Map<String,Object> map = this.getPackProdList(product);
                product.setProductList((List<Product>) map.get("productList"));
                product.setPackageList((List<ProdPackage>) map.get("prodPackageList"));
                break;
            default:
                break;
        }

        result.put("newRow",product);
        return result;
    }


    /**
     * 产品类型为Prod时带出属性信息
     * @author  wangdawei
     * @param product
     * @return
     * @throws Exception 异常信息
     */
    public List<ProdAttr> getProdAttrList(Product product) {
        List<ProdAttr> prodAttrList = new ArrayList<>();
        if (null == product) {
            throw  new ServiceException("REPORT-007");
        }
        try {
            ProdAttr prodAttr = new ProdAttr();
            prodAttr.setPageFlag(false);
            prodAttr.setProdId(product.getId());
            prodAttrList = prodAttrService.queryByExamplePage(prodAttr);
        } catch (Exception ex) {
            LCLogger.withException(ex);
        }
        return prodAttrList;
    }

    /**
     * 产品类型为Good时带出关联产品
     * @author  wangdawei
     * @param product
     * @return
     * @throws Exception 异常信息
     */
    public List<Product> getGoodProdList(Product product) {
        List<Product> prodList = new ArrayList<>();
        if (null == product) {
            throw  new ServiceException("REPORT-007");
        }
        try {
            Product prod = new Product();
            prod.setPageFlag(false);
            prod.setParentProdId(product.getId());
            prodList = queryByExamplePage(prod);
        } catch (Exception ex) {
            LCLogger.withException(ex);
        }
        return prodList;
    }

    /**
     * 产品类型为Pack时带出关联产品
     * @author  wangdawei
     * @param product
     * @return
     * @throws Exception 异常信息
     */
    public Map<String,Object> getPackProdList(Product product) {
        Map<String,Object> map = new HashMap<>(4);
        List<ProdPackage> prodPackageList = new ArrayList<>();
        List<Product> productList = new ArrayList<>();
        if (null == product) {
            throw  new ServiceException("REPORT-007");
        }
        try {
            ProdPackage  prodPackage = new ProdPackage();
            prodPackage.setPageFlag(false);
            prodPackage.setPackageId(product.getId());
            prodPackageList = prodPackageService.queryByExamplePage(prodPackage);
            for (ProdPackage pack : prodPackageList) {
                Product prod =  new Product();
                prod.setId(pack.getProductId());
                prod = productMapper.queryById(prod);
                productList.add(prod);
            }
        } catch (Exception ex) {
            LCLogger.withException(ex);
        }
        map.put("productList",productList);
        map.put("prodPackageList",prodPackageList);
        return map;
    }
    /**
     * 编辑小程序产品
     * @author  wangdawei
     * @param product
     * @return
     * @throws Exception 异常信息
     */

    @Override
    @Transactional(rollbackFor = ServiceException.class)
    public Map<String, Object> updateMpProd(Product product) throws Exception {
        if (null == product) {
            throw new ServiceException("REPORT-007");
        }
        Map<String,Object> map = this.getMpProdInfo(product);
        //校验是否维护小程序
        this.beforUpdate(product);
        // 获取数据库的数据
        Product oldProduct = (Product)map.get("newRow");
        Long prodId = product.getId();
        // 编辑产品主图
        List<Attachment> attachmentList = product.getAttachmentList();
        for (Attachment attachment : attachmentList) {
            if ("Y".equals(attachment.getAttr1())) {
                product.setProdImgId(attachment.getId());
            }
        }
        Boolean flag1 = checkProdCode(product.getProdCode());
        // 校验产品编码是否存在
        if (!oldProduct.getProdCode().equals(product.getProdCode()) &&  flag1) {
            throw new ServiceException("PRODUCT-023");
        }
        productMapper.update(product);
        // 新老价格不相等，价格历史表新增一条数据
        Boolean flag = false;
        if ( product.getProdPrice() != null ) {
            flag = !product.getProdPrice().equals(oldProduct.getProdPrice());
        }
        String date = DateUtil.dateToStr(new Date(),"yyyy-MM-dd HH:mm:ss");
        if (flag) {
            ProdPriceHistory prodPriceHistory = new ProdPriceHistory();
            prodPriceHistory.setHeadId(prodId);
            prodPriceHistory.setStartTime(date);
            prodPriceHistory.setPrice(product.getProdPrice());
            ProdPriceHistory phs = new ProdPriceHistory();
            phs.setHeadId(product.getId());
            phs.setPageFlag(false);
            List<ProdPriceHistory>  prodPriceHistoryList = prodPriceHistoryService.queryByExamplePage(phs);
            for (ProdPriceHistory prodPriceHistory1 : prodPriceHistoryList) {
                if (StringUtils.isBlank(prodPriceHistory1.getEndTime())) {
                    prodPriceHistory1.setEndTime(date);
                    prodPriceHistoryService.update(prodPriceHistory1);
                }
            }
            prodPriceHistoryService.insert(prodPriceHistory);
        }
        // 编辑产品tag
        this.updateProdTag(product,oldProduct);
        switch (product.getProdGoodType()) {
            // 产品类型为Prod时的编辑
            case "Prod":
                List<ProdAttr> prodAttrList = product.getProdAttrList();
                for (ProdAttr prodAttr : prodAttrList) {
                    Long prodAttrId = prodAttr.getId();
                    if ("NEW".equals(prodAttr.getRow_status())) {
                        if (prodAttrId == null) {
                            prodAttrId = keyGenerateService.keyGenerate();
                            prodAttr.setId(prodAttrId);
                        }
                        prodAttr.setProdId(prodId);
                        prodAttrService.insert(prodAttr);
                        //更新数据
                    } else if ("UPDATE".equals(prodAttr.getRow_status())) {
                        if (prodAttrId == null) {
                            throw new ServiceException("PRODUCT-027");
                        }
                        prodAttrService.update(prodAttr);
                    }
                }
                break;
            // 产品类型为Good时带出关联产品
            case "Good":
                List<Product> productList = product.getProductList();
                for (Product product1 : productList ) {
                    if ("NEW".equals(product1.getRow_status())) {
                        product1 = this.queryById(product1);
                        product1.setParentProdId(prodId);
                        this.update(product1);
                    }
                }
                break;
            // 产品类型为Pack时带出组合产品信息
            case "Pack":
                List<ProdPackage> prodPackageList = product.getPackageList();
                for (ProdPackage prodPackage : prodPackageList) {
                    if ("NEW".equals(prodPackage.getRow_status())) {
                        prodPackageService.insert(prodPackage);
                    } else if ("UPDATE".equals(prodPackage.getRow_status())) {
                        if (prodPackage.getId() == null) {
                            throw new ServiceException("PRODUCT-028");
                        }
                        prodPackageService.update(prodPackage);
                    }
                }
                break;
            default:
                break;
        }
        // 数据删除
        this.deleteProd(product,oldProduct);

        map.put("success", true);
        map.put("newRow",product);
        return map;
    }
    /**
     * 编辑产品tag
     * @author  wangdawei
     * @param product
     * @return
     * @throws Exception 异常信息
     */

    public Product updateProdTag(Product product,Product oldProduct) {
        if (null == product) {
            throw  new ServiceException("REPORT-007");
        }
        try {
            // 编辑产品下的删除信息
            // 编辑产品标签
            List<ProdTag> prodProdTagList = product.getProdTagList();
            List<ProdTag> oldProdTagList = oldProduct.getProdTagList();
            for (ProdTag prodTag : prodProdTagList) {
                if ("NEW".equals(prodTag.getRow_status())) {
                    prodTagService.insert(prodTag);
                }
            }
            for (int i = 0; oldProdTagList != null && prodProdTagList != null && i < oldProdTagList.size(); i++) {
                ProdTag oldProdTag = oldProdTagList.get(i);
                boolean delFlag = true;
                for (int j = 0; oldProdTagList != null && j < prodProdTagList.size(); j++) {
                    if (oldProdTag.getId().equals(prodProdTagList.get(j).getId())) {
                        delFlag = false;
                        break;
                    }
                }
                if (delFlag) {
                    prodTagService.deleteById(oldProdTag);
                }
            }
        } catch (Exception ex) {
            LCLogger.withException(ex);
        }
        return product;
    }

    /**
     * 删除数据
     * @author  wangdawei
     * @param product
     * @return
     * @throws Exception 异常信息
     */
    public Product deleteProd(Product product,Product oldProduct) {
        if (null == product) {
            throw  new ServiceException("REPORT-007");
        }
        try {
            // 编辑产品下的删除信息
            switch (product.getProdGoodType()) {
                // 产品类型为Prod时的删除属性信息
                case "Prod":
                    List<ProdAttr> prodAttrList = product.getProdAttrList();
                    List<ProdAttr> oldProdAttrList = oldProduct.getProdAttrList();
                    for (int i = 0; oldProdAttrList != null && prodAttrList != null && i < oldProdAttrList.size(); i++) {
                        ProdAttr oldProdAttr = oldProdAttrList.get(i);
                        boolean delFlag = true;
                        for (int j = 0; oldProdAttrList != null && j < prodAttrList.size(); j++) {
                            if (oldProdAttr.getId().equals(prodAttrList.get(j).getId())) {
                                delFlag = false;
                                break;
                            }
                        }
                        if (delFlag) {
                            prodAttrService.deleteById(oldProdAttr);
                        }
                    }
                    break;
                // 产品类型为Good时删除产品信息
                case "Good":
                    List<Product> productList = product.getProductList();
                    List<Product> oldProductList = oldProduct.getProductList();
                    for (int i = 0; oldProductList != null && productList != null && i < oldProductList.size(); i++) {
                        Product oldProd = oldProductList.get(i);
                        boolean delFlag = true;
                        for (int j = 0; oldProductList != null && j < productList.size(); j++) {
                            if (oldProd.getId().equals(productList.get(j).getId())) {
                                delFlag = false;
                                break;
                            }
                        }
                        if (delFlag) {
                            oldProd.setParentProdId(Long.parseLong(""));
                            productMapper.update(oldProd);
                        }
                    }
                    break;
                // 产品类型为Pack时删除组合产品信息
                case "Pack":
                    List<ProdPackage> packageList = product.getPackageList();
                    List<ProdPackage> oldpackageList = oldProduct.getPackageList();
                    for (int i = 0; oldpackageList != null && packageList != null && i < oldpackageList.size(); i++) {
                        ProdPackage oldPackage = oldpackageList.get(i);
                        boolean delFlag = true;
                        for (int j = 0; oldpackageList != null && j < packageList.size(); j++) {
                            if (oldPackage.getId().equals(packageList.get(j).getId())) {
                                delFlag = false;
                                break;
                            }
                        }
                        if (delFlag) {
                            prodPackageService.deleteById(oldPackage);
                        }
                    }
                    break;
                default:
                    break;
            }
        } catch (Exception ex) {
            LCLogger.withException(ex);
        }
        return product;
    }

    /**
     * 根据id查询品牌系列信息
     * @author KuangRuifeng
     * @date 2019/1/8
     * @param productId 行id
     * @return 查询结果
     * @throws Exception 异常信息
     */
    @Override
    public Product queryBrandSeriesById(Long productId) throws Exception {
        Product productParam = new Product();
        productParam.setId(productId);
        return productMapper.queryBrandSeriesById(productParam);
    }

    /**
     * 校验产品编码
     * @author wangdawei
     * @param prodCode 产品编码
     * @return 查询结果
     * @throws Exception 异常信息
     */
    @Override
    public Boolean checkProdCode(String prodCode) throws Exception {
        Product product = new Product();
        product.setPageFlag(false);
        product.setAnonymousFlag("Y");
        product.setProdCode(prodCode);
        List<Product> productList = this.queryByExamplePage(product);
        Boolean flag = false;
        if (productList.size() > 0) {
            flag = true;
        }
        return flag;
    }


    /**
     * PC端-没有维护小程序参数的情况下，点击‘小程序上架’按钮需要抛出异常
     * @author 路江
     * @param entity
     * @throws Exception
     */
    @Override
    public void beforUpdate(Product entity) throws Exception {
        // 如果要发布到小程序，首先得校验是否有维护好小程序信息
        String mpVisible = "Y";
        if (StringUtils.equals(entity.getMpVisible(),mpVisible)) {
            Mp mp = new Mp();
            mp.setPageFlag(false);
            mp.setValidFlag("Y");
            mp.setMainFlag("Y");
            List<Mp> mpList = mpService.queryByExamplePage(mp);
            if (mpList.size() < 1) {
                throw new Exception("该帐套未维护小程序信息");
            }
        }
    }

    /**
     * 把图片文件转化为base64编码
     * @author  wangdawei
     * @date  2019-4-2
     * @param in InputStream
     */
    public String getBase64FromInputStream(InputStream in) throws Exception {
        // 将图片文件转化为字节数组字符串，并对其进行Base64编码处理
        BASE64Encoder encoder = new BASE64Encoder();
        byte[] data = null;
        // 读取图片字节数组
        try {
            ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
            byte[] buff = new byte[100];
            int rc = 0;
            while ((rc = in.read(buff, 0, 100)) > 0) {
                swapStream.write(buff, 0, rc);
            }
            data = swapStream.toByteArray();
        } catch (IOException e) {
            LCLogger.withException(e);
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    LCLogger.withException(e);
                }
            }
        }
        return encoder.encode(data);
    }

    @Override
    public List<Product> queryByOrgIdPage(Product product) throws Exception {
        return productMapper.queryByOrgIdPage(product);
    }

    /**
     * 从门店迁移根据物流追溯码查询产品功能
     * @author 姚江漪
     * @date 2019/08/14 16:49
     */
    @Override
    public Map<String, Object> queryProductByLogCode(Product product) throws Exception {
        String userName = PropertyUtil.getCommonProperty(MOCK_USERNAME_KEY);
        TokenUtils.setLogin(userName);
        Map<String, Object> result = new HashMap<>();
        // 产品条形码
        String queryCode = product.getProdBarcode();
        Product queryObj = new Product();
        queryObj.setProdBarcode(queryCode);
        List<Product> products = productMapper.queryByExamplePage(queryObj);
        int size = products.size();
        if (size == 0) {
            result.put("rows", new ArrayList<Product>());
            result.put("total", 0);
            result.put("result", "没有找到与条码" + queryCode + "对应的商品");
            logger.info("没有找到与条码[{}]对应的商品", queryCode);
            return result;
        }
        if (size >= 2) {
            result.put("rows", products);
            result.put("total", size);
            result.put("result", "根据条码" + queryCode + "找到" + size + "条产品");
            logger.info("根据条码[{}]找到[{}]条产品", queryCode, size);
        }
        result.put("rows", products);
        result.put("total", size);
        return result;
    }

    /**
     * 物流追溯码查询产品未找到时进行手工录入
     * @author 姚江漪
     * @date 2019/08/14 16:49
     */
    @Override
    @SuppressWarnings("unchecked")
    public Product queryProductByManual(Product product) throws Exception {
        // 数量取前端传入的数量
        Map<String, Object> logCodeResult = queryProductByLogCode(product);
        String result = String.valueOf(logCodeResult.get("result"));
        if (StringUtils.isNotBlank(result)) {
            throw new BasicServiceException(result);
        }
        List<Product> products = (List<Product>) logCodeResult.get("rows");
        // 以手动输入的产品为准,将前端手动输入的产品数量返回前端
        products.get(0).setCount(product.getCount());
        return products.get(0);
    }
}
